﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Common.Constants;
using Common.Helper;
using Common.Interface;
using EntityFrameworkExtension;
using EntityFrameworkExtension.Interface;
using MainProcessor.ContextProcessor;
using MainProcessor.Interface;
using NUnit.Framework;
using Rhino.Mocks;

namespace Test.Main.ContextProcessor
{
    [TestFixture]
    public class ReplacedInterface1ProcessorTests
    {
        private IDataCache dataCache;
        private ILatestParentMeasures latestParentMeasures;
        private IEfContext efContext;
        private IDataController dataController;
        private ReplacedInteface1Processor replacedInteface1Processor;

        private const int MappingId = 321;
        private static readonly Guid Guid = new Guid("720d3c24-3fe9-4ce1-ae5c-3337b949c773");
        private static readonly List<ReplacedInteface1> Funds = new List<ReplacedInteface1> { new ReplacedInteface1 { Guid = Guid } };

        [SetUp]
        public void SetUp()
        {
            dataCache = MockRepository.GenerateMock<IDataCache>();
            latestParentMeasures = MockRepository.GenerateMock<ILatestParentMeasures>();
            efContext = MockRepository.GenerateMock<IEfContext>();
            dataController = MockRepository.GenerateMock<IDataController>();

            replacedInteface1Processor = new ReplacedInteface1Processor(dataController, dataCache, latestParentMeasures);
        }

        [TearDown]
        public void Teardown()
        {
            dataCache.VerifyAllExpectations();
            dataController.VerifyAllExpectations();
            latestParentMeasures.VerifyAllExpectations();
            efContext.VerifyAllExpectations();
            
        }

        [Test]
        public void NewFundShouldBePickedUpAndInserted()
        {
            var xml = XElement.Parse(ConstantXml.TestString);

            SetUpElementDataExpectations();

            efContext.Expect(x => x.SelectCurrent<ReplacedInteface1>(null)).IgnoreArguments().Return(default(ReplacedInteface1));

            efContext.Expect(x => x.AddToObjectList(Arg<ReplacedInteface1>.Matches(y => y.Guid == Guid
                 && y.NoOfEmployees == 2
                 && y.GenerationID == 22
                 && y.AssetClassID == 6
                 && y.CapacityTotal == 101m))).Repeat.Once();


            replacedInteface1Processor.ExtractXml(xml);
            replacedInteface1Processor.PopulateEf(efContext);
        }

        [Test]
        public void ExistingFundShouldBeUpdated()
        {
            var xml = XElement.Parse(ConstantXml.TestString);

            SetUpElementDataExpectations();

            efContext.Expect(x => x.SelectCurrent<ReplacedInteface1>(null)).IgnoreArguments().Return(Funds[0]);
            efContext.Expect(x => x.AddToObjectList(Arg<ReplacedInteface1>.Matches(y => y.Guid == Guid))).Repeat.Never();

            replacedInteface1Processor.ExtractXml(xml);
            replacedInteface1Processor.PopulateEf(efContext);

            Assert.AreEqual(Guid, Funds[0].Guid);
            Assert.AreEqual(22, Funds[0].GenerationID);
            Assert.AreEqual(6, Funds[0].AssetClassID);
            Assert.AreEqual(101m, Funds[0].CapacityTotal);
            Assert.AreEqual(2, Funds[0].NoOfEmployees);
        }

        private void SetUpElementDataExpectations()
        {
            dataController.Expect(x => x.GetGuidIntMappings1(Arg<int>.Matches(y => y == MappingId), Arg<IEfContext>.Is.Anything)).Return(Guid);
           
            dataCache.Expect(x => x.GetId<ReferenceTypeTable1, int>("GenName1", efContext)).Return(22);
            latestParentMeasures.Expect(x => x.TotalCapacity).Return(101m);
            latestParentMeasures.Expect(x => x.TotalEmployees).Return(2);
            latestParentMeasures.Expect(
                x =>
                x.Initialise(null, XmlConstants.ParentMeasure, XmlConstants.LegacyType,
                             ParentMeasureType.AuM.ToDescription())).IgnoreArguments().Return(true);
            dataCache.Expect(x => x.GetId<ReferenceTypeTable2, int>("AssetClassName1", efContext)).Return(6);
        }
    }
}
